#include "../include/linklist.h"

#include <stdlib.h>
#include <stdio.h>

Status LinkListInit( PLinkList L )
{
    if ( L == NULL )	{
        return PARAMERROR;
    }

    L->head = ( PNode ) malloc( sizeof( Node ) );

    if ( L->head == NULL ) {
        return MEMERROR;
    }

    L->head->pNext = NULL;
    L->length = 0;
    return OK;
}

PNode LinkListGetPriorElem( PLinkList L, int pos )
{
    Node *ppre = NULL;
    int nCnt = 1;

    if ( L == NULL || L->length + 1 < pos ) {
        return NULL;
    }

    ppre = L->head;

    while ( nCnt != pos ) {
        ppre = ppre->pNext;
        ++nCnt;
    }

    return ppre;
}

Status LinkListInsertElem( PLinkList L, int pos, ElemType elem )
{
    int nCnt = 1;
    Node *ppre = NULL;
    Node *pnew = NULL;

    ppre = LinkListGetPriorElem( L, pos );

    if ( ppre == NULL ) {
        return PARAMERROR;
    }

    pnew = ( PNode )malloc( sizeof( Node ) );

    if ( pnew == NULL ) {
        return MEMERROR;
    }

    pnew->elem = elem;
    pnew->pNext = ppre->pNext;

    ppre->pNext = pnew;

    ++( L->length );

    return OK;
}

Status LinkListDeleteElem( PLinkList L, int pos, ElemType *pElem )
{
    int nCnt = 1;
    Node *ppre = NULL;
    Node *pdestory = NULL;

    ppre = LinkListGetPriorElem( L, pos );

    if ( ppre == NULL ) {
        return PARAMERROR;
    }

    pdestory = ppre->pNext;
    ppre->pNext = pdestory->pNext;

    *pElem = pdestory->elem;
    free( pdestory );

	--(L->length);

    return OK;
}

Status LinkListReset( PLinkList L )
{
    PNode pnext = NULL;
    PNode pcur = NULL;

    if ( L == NULL ) {
        return PARAMERROR;
    }

    pcur = L->head->pNext;
    pnext = pcur->pNext;

    while ( pnext != NULL ) {
        free( pcur );
        pcur = pnext;
        pnext = pcur->pNext;
    }

    free( pcur );

    L->length = 0;
    L->head->pNext = NULL;

    return OK;
}

Status LinkListCreate( PLinkList L, ElemType *pVec, int length )
{
    int nCnt = 0;
    PNode pEnd = NULL;
    PNode pnew = NULL;

    if ( L == NULL ) {
        return PARAMERROR;
    }

    if ( L->length != 0 ) {
        LinkListReset( L );
    }

    pEnd = L->head;

    for ( nCnt = 1; nCnt <= length; ++nCnt ) {
        pnew = ( PNode )malloc( sizeof( Node ) );
        pnew->elem = pVec[nCnt - 1];
        pnew->pNext = NULL;
        pEnd->pNext = pnew;
        pEnd = pnew;
    }

    L->length = length;

    return OK;
}

Status LinkListGetElem( PLinkList L, int pos, ElemType *pElem )
{
    int nCnt = 1;
    PNode pcur = NULL;

    if ( L == NULL || L->length < pos || pElem == NULL ) {
        return PARAMERROR;
    }

    pcur = L->head->pNext;

    while ( nCnt != pos ) {
        pcur = pcur->pNext;
		++nCnt;
    }

    *pElem = pcur->elem;

    return OK;
}

Status LinkListPrint( PLinkList L )
{
    PNode pcur = NULL;

    if ( L == NULL ) {
        return PARAMERROR;
    }

    pcur = L->head->pNext;
    printf( "[" );

    while ( pcur != NULL ) {
        if ( pcur->pNext != NULL ) {
            printf( "%d, ", pcur->elem );
            pcur = pcur->pNext;
            continue;
        }

        printf( "%d", pcur->elem );
        pcur = pcur->pNext;
    }

    printf( "]\n" );

    return OK;
}

Status LinkListUnInit( PLinkList L )
{
	if (L == NULL)
	{
		return PARAMERROR;
	}

	L->length = 0;
	free(L->head);
	L->head = NULL;

	return OK;
}
